<template>
  <div id="workproForm">

    <el-menu
      default-active="0"
      class="el-menu-vertical-demo"
    >
      <div>
        <el-button
          style="width:100%;"
          @click="addMenu()"
        ><i class="el-icon-edit"/></el-button>
      </div>
      <el-menu-item
        v-for="(item,index) in menu"
        :key="index"
        :index="index+''"
        style="padding-left:10px;"
        @click="xuanran(item.type)"
      >
        <i
          class="el-icon-delete"
          @click="delMenu(item.id)"
          @click.stop
        />
        <el-popover
          trigger="hover"
          placement="right"
        >
          <span
            slot="reference"
            class="spans"
          >{{ item.type }}</span>

          {{ item.type }}

        </el-popover>
      </el-menu-item>
    </el-menu>
    <div id="mainBox">

      <div id="tit">
        数据来源:
        <el-select
          v-model="sourceType"
          placeholder="请选择"
        >
          <el-option
            v-for="item in dataOptions"
            :key="item.key"
            :label="item.desc"
            :value="item.key"
          />
        </el-select>
        <el-button type="warning" style="margin-left: 16px;float: right" icon="el-icon-edit-outline" circle @click="opens"/>
        <el-drawer
          :visible.sync="drawer"
          :with-header="false"
          :before-close="handleClose"
          title="我是标题"
          size="50%">
          <div id="areaBox">
            <div class="in-coder-panel">
              <textarea
                id="code"
                v-model="codes"
              />
              <el-select
                v-model="mode"
                class="code-mode-select"
                @change="changeMode"
              >
                <el-option
                  v-for="mode in modes"
                  :key="mode.value"
                  :label="mode.label"
                  :value="mode.value"
                />
              </el-select>
            </div>
          </div>
        </el-drawer>
      </div>
      <div id="boxTit">
        <el-popover
          placement="top-start"
          width="200"
          trigger="hover"
        >
          <vue-editor
            v-model="helpArrays.TEMPLATE_VARS"
            :editor-toolbar="customToolbar"
          />
          <i
            slot="reference"
            class="el-icon-question"
            style="color:#409eff;margin-left:5px;font-size:15px;float:left"
          />
        </el-popover>
        <span class="tit"> {{ descName }} </span>
        <span class="tit">></span>
        <span class="tit">{{ name }} 模板编辑器</span>
        <i
          class="el-icon-success"
          @click="btnSave"
        />
      </div>

      <div class="in-coder-panel">
        <textarea
          ref="textarea"
          v-model="code"
        />
        <el-select
          v-model="mode"
          class="code-mode-select"
          @change="changeMode"
        >
          <el-option
            v-for="mode in modes"
            :key="mode.value"
            :label="mode.label"
            :value="mode.value"
          />
        </el-select>
      </div>
    </div>
    <el-dialog
      :visible.sync="dialogVisible"
      title="创建模板"
      width="500px"
    >
      <div>模板名称：<el-input v-model="addTemplateName"/>
      </div>
      <!-- <el-input></el-input> -->

      <div>数据来源：<el-select
        v-model="sourceTypes"
        placeholder="请选择"
      >
        <el-option
          v-for="item in dataOptions"
          :key="item.key"
          :label="item.desc"
          :value="item.key"
        />
      </el-select>
      </div>

      <span
        slot="footer"
        class="dialog-footer"
      >
        <el-button @click="addTemplate(false)">取 消</el-button>
        <el-button
          type="primary"
          @click="addTemplate(true)"
        >确 定</el-button>
      </span>
    </el-dialog>
  </div>

</template>

<script >
import {
  tedescMain,
  tedescItemSave,
  tedescItem,
  docwindow,
  tdescDelete,
  gtmDesc,
  upConsole
} from '@/api/page'
import { VueEditor } from 'vue2-editor'
// 引入全局实例
import _CodeMirror from 'codemirror'

// 核心样式
import 'codemirror/lib/codemirror.css'
// 引入主题后还需要在 options 中指定主题才会生效
import 'codemirror/theme/cobalt.css'

// 需要引入具体的语法高亮库才会有对应的语法高亮效果
// codemirror 官方其实支持通过 /addon/mode/loadmode.js 和 /mode/meta.js 来实现动态加载对应语法高亮库
// 但 vue 貌似没有无法在实例初始化后再动态加载对应 JS ，所以此处才把对应的 JS 提前引入
import 'codemirror/mode/javascript/javascript.js'
import 'codemirror/mode/css/css.js'
import 'codemirror/mode/xml/xml.js'
import 'codemirror/mode/clike/clike.js'
import 'codemirror/mode/markdown/markdown.js'
import 'codemirror/mode/python/python.js'
import 'codemirror/mode/r/r.js'
import 'codemirror/mode/shell/shell.js'
import 'codemirror/mode/sql/sql.js'
import 'codemirror/mode/swift/swift.js'
import 'codemirror/mode/vue/vue.js'

// 尝试获取全局实例
const CodeMirror = window.CodeMirror || _CodeMirror

export default {
  name: 'InCoder',
  components: {
    VueEditor
  },
  props: {
    // 外部传入的内容，用于实现双向绑定
    value: String,
    // 外部传入的语法类型
    language: {
      type: String,
      default: null
    }
  },
  data() {
    return {
      drawer: false,
      dialogVisible: false,
      arr: [],
      customToolbar: [],
      helpArrays: [],
      help: '',
      descName: '',
      source: '',
      tit: '',
      name: '',
      itemId: '',
      data: {
        mid: '2',
        moduleType: ''
      },
      dataOptions: [],
      addTemplateName: '',
      sourceTypes: '',
      menu: '',
      items: '',
      sourceType: '',
      // 内部真实的内容
      code: '',
      codes: '',
      // 默认的语法类型
      mode: 'javascript',
      // 编辑器实例
      coder: null,
      coders: null,
      // 默认配置
      options: {
        // 缩进格式
        tabSize: 2,
        // 主题，对应主题库 JS 需要提前引入
        theme: 'cobalt',
        // 显示行号
        lineNumbers: true,
        line: true,
        smartIndent: false,
        electricChars: false
      },
      // 支持切换的语法高亮类型，对应 JS 已经提前引入
      // 使用的是 MIME-TYPE ，不过作为前缀的 text/ 在后面指定时写死了
      modes: [
        {
          value: 'css',
          label: 'CSS'
        },
        {
          value: 'javascript',
          label: 'Javascript'
        },
        {
          value: 'html',
          label: 'XML/HTML'
        },
        {
          value: 'x-java',
          label: 'Java'
        },
        {
          value: 'x-objectivec',
          label: 'Objective-C'
        },
        {
          value: 'x-python',
          label: 'Python'
        },
        {
          value: 'x-rsrc',
          label: 'R'
        },
        {
          value: 'x-sh',
          label: 'Shell'
        },
        {
          value: 'x-sql',
          label: 'SQL'
        },
        {
          value: 'x-swift',
          label: 'Swift'
        },
        {
          value: 'x-vue',
          label: 'Vue'
        },
        {
          value: 'markdown',
          label: 'Markdown'
        }
      ],
      isopen: true
    }
  },
  mounted() {
    var that = this
    // 初始化
    this.descName = localStorage.getItem('proName')
    this._initialize()
    this.data.mid = localStorage.getItem('mid')
    this.data.moduleType = localStorage.getItem('templateType')
    this.onload()

    this.arr = ['TEMPLATE_VARS']

    docwindow(this.arr)
      .then(response => {
        if (response.data.code == 'SUCCESS') {
          this.helpArrays = response.data.data
        } else {
          alert(response.data.message)
        }
      })
      .catch(error => {
        alert(error.response.data.message)
      })
    document.addEventListener('keydown', function(e) {
      if (e.keyCode == 83 && (navigator.platform.match('Mac') ? e.metaKey : e.ctrlKey)) {
        e.preventDefault()
        that.btnSave()
      }
    })
  },
  methods: {
    _initializes() {
      this.isopen = false
      console.log('123')
      // 初始化编辑器实例，传入需要被实例化的文本域对象和默认配置
      const myTextarea = document.getElementById('code')
      console.log(myTextarea, '2')
      this.coders = CodeMirror.fromTextArea(myTextarea, this.options)
      console.log(this.coders, '1')
      // 编辑器赋值
      this.coders.setValue(this.codes)
      console.log(this.codes, '2')

      // 支持双向绑定
      this.coders.on('change', coders => {
        this.codes = coders.getValue()

        if (this.$emit) {
          this.$emit('input', this.codes)
        }
      })

      // 尝试从父容器获取语法类型
      if (this.language) {
        // 获取具体的语法类型对象
        const modeObj = this._getLanguage(this.language)

        // 判断父容器传入的语法是否被支持
        if (modeObj) {
          this.mode = modeObj.label
        }
      }
    },
    // 初始化
    _initialize() {
      // 初始化编辑器实例，传入需要被实例化的文本域对象和默认配置
      this.coder = CodeMirror.fromTextArea(this.$refs.textarea, this.options)
      // 编辑器赋值
      this.coder.setValue(this.value || this.code)

      // 支持双向绑定
      this.coder.on('change', coder => {
        this.code = coder.getValue()

        if (this.$emit) {
          this.$emit('input', this.code)
        }
      })

      // 尝试从父容器获取语法类型
      if (this.language) {
        // 获取具体的语法类型对象
        const modeObj = this._getLanguage(this.language)

        // 判断父容器传入的语法是否被支持
        if (modeObj) {
          this.mode = modeObj.label
        }
      }
    },
    // 获取当前语法类型
    _getLanguage(language) {
      // 在支持的语法类型列表中寻找传入的语法类型
      return this.modes.find(mode => {
        // 所有的值都忽略大小写，方便比较
        const currentLanguage = language.toLowerCase()
        const currentLabel = mode.label.toLowerCase()
        const currentValue = mode.value.toLowerCase()

        // 由于真实值可能不规范，例如 java 的真实值是 x-java ，所以讲 value 和 label 同时和传入语法进行比较
        return (
          currentLabel === currentLanguage || currentValue === currentLanguage
        )
      })
    },
    // 更改模式
    changeMode(val) {
      // 修改编辑器的语法配置
      this.coder.setOption('mode', `text/${val}`)

      // 获取修改后的语法
      const label = this._getLanguage(val).label.toLowerCase()

      // 允许父容器通过以下函数监听当前的语法值
      this.$emit('language-change', label)
    },
    // 渲染
    xuanran(a) {
      if (this.name !== '') {
        this.save(this.name)
      }
      // console.log(this.save())

      var item = {
        mid: this.data.mid,
        moduleType: this.data.moduleType,
        templateType: a
      }

      tedescItem(item)
        .then(response => {
          if (response.data.code == 'SUCCESS') {
            this.items = response.data.data.desc

            if (response.data.data.desc.sourceType == undefined) {
              this.sourceType = ''
            } else {
              this.sourceType = response.data.data.desc.sourceType
            }

            for (var i = 0; i < this.dataOptions.length; i++) {
              if (
                this.dataOptions[i].key == response.data.data.desc.sourceType
              ) {
                this.source = this.dataOptions[i].desc
              }
            }

            this.coder.setValue(this.items.code)
            this.name = this.items.type
            this.itemId = this.items.id
          } else {
            alert(response.data.message)
          }
        })
        .catch(error => {
          // alert(error.response.data.message);
        })
    },
    // 保存
    save(a) {
      var save = {
        mid: this.data.mid,
        moduleType: this.data.moduleType,
        templateType: a,
        id: this.itemId,
        code: this.code,
        packages: '1',
        sourceType: this.sourceType
      }
      if (save.sourceType == '') {
        alert('错误')
        return false
      }
      tedescItemSave(save)
        .then(response => {
          if (response.data.code == 'SUCCESS') {
            this.openFullScreen()
            setTimeout(() => {
              this.loading.close()
            }, 1000)
          } else {
            alert(response.message)
          }
        })
        .catch(error => {
          alert(error.response.message)
        })
    },
    // 按钮保存
    btnSave() {
      var save = {
        mid: this.data.mid,
        moduleType: this.data.moduleType,
        templateType: this.name,
        id: this.itemId,
        code: this.code,
        packages: '1',
        sourceType: this.sourceType
      }
      if (save.sourceType == '') {
        alert('错误')
        return
      }
      tedescItemSave(save)
        .then(response => {
          if (response.data.code == 'SUCCESS') {
            this.openFullScreen()
            setTimeout(() => {
              this.loading.close()
            }, 1000)
          } else {
            alert(response.data.message)
          }
        })
        .catch(error => {
          alert(error)
        })
    },
    openFullScreen() {
      this.loading = this.$loading({
        lock: true,
        text: 'Loading',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)'
      })
    },
    // 添加自定义模板弹框
    addMenu() {
      console.log(111)
      this.dialogVisible = true
    },
    // 添加自定义模板
    addTemplate(a) {
      if (a == true) {
        var save = {
          mid: this.data.mid,
          moduleType: this.data.moduleType,
          templateType: this.addTemplateName,
          sourceType: this.sourceTypes,
          code: ''
        }

        tedescItemSave(save)
          .then(response => {
            if (response.data.code == 'SUCCESS') {
              this.openFullScreen()
              setTimeout(() => {
                this.loading.close()
                this.addTemplateName = ''
                this.dialogVisible = false
                this.onload()
              }, 1000)
            } else {
              alert(response.message)
            }
          })
          .catch(error => {
            alert(error.response.message)
          })
      } else {
        this.addTemplateName = ''
        this.dialogVisible = false
      }
    },
    delMenu(id) {
      var obj = {
        id: id
      }

      this.$confirm('此操作将永久删除该模板', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        tdescDelete(obj).then(response => {
          if (response.data.code == 'SUCCESS') {
            this.openFullScreen()
            setTimeout(() => {
              this.onload()
              this.loading.close()
            }, 1000)
          }
        })
      })
    },
    onload() {
      tedescMain(this.data)
        .then(response => {
          if (response.data.code == 'SUCCESS') {
            this.menu = response.data.data.menus
            this.dataOptions = response.data.data.sourceTypes
            this.xuanran(this.menu[0].type)
          } else {
            alert(response.data.message)
          }
        })
        .catch(error => {
          alert(error.response.data.message)
          this.$router.push('/admin')
        })
    },
    handleClose(done) {
      var save = {
        id: this.data.mid,
        varConsole: this.codes
      }
      upConsole(save)
        .then(response => {
          if (response.data.code == 'SUCCESS') {
            done()
          } else {
            alert(response.message)
          }
        })
        .catch(error => {
          alert(error.response.message)
        })
      // console.log(this.codes)
    },
    opens() {
      var that = this
      this.codes = localStorage.getItem('midConsole')
      this.drawer = true
      if (this.isopen) {
        setTimeout(function() {
          that._initializes()
        }, 0)
      }
    }
  }
}
</script>

<style>
#workproForm .in-coder-panel {
  flex-grow: 1;
  display: flex;
  position: relative;
}

#workproForm .CodeMirror {
  /* margin-top: 20px; */
  flex-grow: 1;
  z-index: 1;
  font-size: 15px;
}

#workproForm .CodeMirror-code {
  line-height: 19px;
}

#workproForm .code-mode-select {
  position: absolute;
  z-index: 2;
  right: 10px;
  top: 20px;
  max-width: 130px;
}
#workproForm .el-menu {
  width: 14%;
  margin-right: 20px;
  float: left;
  border-right: 1px solid #623f18;
  height: 92vh;
}

#workproForm .el-menu-item {
  height: 28px;
  line-height: 28px;
  border-top: 1px solid #ccc;
}

#workproForm #mainBox {
  float: left;
  margin-top: 5px;
  width: 83%;
  height: 77vh;
}

#workproForm #mainBox #boxTit {
  height: 40px;
  width: 100%;
  background: #623f18;
}
#workproForm #mainBox #boxTit i {
  cursor: pointer;
  float: right;
  line-height: 40px;
  margin-right: 10px;
  font-size: 25px;
  color: #fff;
}
#workproForm #mainBox #boxTit .tit {
  margin-right: 20px;
  font-size: 20px;
  color: #fff;
  line-height: 40px;
  float: left;
}
#workproForm .in-coder-panel {
  padding: 2px;
  border: 1px solid #623f18;
}
#workproForm .CodeMirror {
  height: 69vh;
}
#workproForm li {
  overflow: hidden;
}
#workproForm .el-dialog .el-input {
  width: 200px;
}
#workproForm .el-dialog .el-input input {
  width: 200px;
  height: 40px;
}
#workproForm #tit{
  font-size: 15px;
  margin-top: 10px;
  margin-bottom: 20px;
}
#workproForm .el-input input{
  height: 40px;
}
  /*滑块*/
#areaBox {
  position: relative;
  border: 1px solid #623f18;
}
#areaBox .code-mode-select {
  position: absolute;
  z-index: 2;
  right: 10px;
  top: 20px;
}
#areaBox .el-input {
  width: 120px;
}
#workproForm #areaBox .CodeMirror {
  height: 100vh;
}
</style>
